/**
 * Copyright 2007-2010 非也
 * All rights reserved. 
 * 
 * This library is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License v3 as published by the Free Software
 * Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along
 * with this library; if not, see http://www.gnu.org/licenses/lgpl.html.
 *
 */
package org.fireflow2.designer.eclipse.commands.workflownode;

import java.util.List;
import java.util.UUID;

import org.fireflow.model.ModelElement;
import org.fireflow.pdl.fpdl20.diagram.ActivityShape;
import org.fireflow.pdl.fpdl20.diagram.basic.Label;
import org.fireflow.pdl.fpdl20.diagram.basic.impl.BoundsImpl;
import org.fireflow.pdl.fpdl20.diagram.basic.impl.LabelImpl;
import org.fireflow.pdl.fpdl20.diagram.basic.impl.PointImpl;
import org.fireflow.pdl.fpdl20.diagram.basic.impl.RectangleImpl;
import org.fireflow.pdl.fpdl20.diagram.impl.ActivityShapeImpl;
import org.fireflow.pdl.fpdl20.diagram.style.BoundsStyle;
import org.fireflow.pdl.fpdl20.diagram.style.Font;
import org.fireflow.pdl.fpdl20.diagram.style.FulfilStyle;
import org.fireflow.pdl.fpdl20.diagram.style.impl.BoundsStyleImpl;
import org.fireflow.pdl.fpdl20.diagram.style.impl.FontImpl;
import org.fireflow.pdl.fpdl20.diagram.style.impl.FulfilStyleImpl;
import org.fireflow.pdl.fpdl20.process.Activity;
import org.fireflow.pdl.fpdl20.process.SubProcess;
import org.fireflow.pdl.fpdl20.process.impl.ActivityImpl;
import org.fireflow2.designer.eclipse.commands.AbstractCreateNodeCommand;
import org.fireflow2.designer.eclipse.commands.service.AbstractServiceCreationCommand;
import org.fireflow2.designer.eclipse.modelwrapper.NodeWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.SubProcessWrapper;
import org.fireflow2.designer.eclipse.modelwrapper.basic.ActivityWrapper;

/**
 * 
 * @author 非也 nychen2000@163.com Fire Workflow 官方网站：www.firesoa.com 或者
 *         www.fireflow.org
 * 
 */
public class CreateActivityCommand extends AbstractCreateNodeCommand {
	protected AbstractServiceCreationCommand serviceCreationCommand = null;

	public void setServiceCreationCommand(AbstractServiceCreationCommand command) {
		serviceCreationCommand = command;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.fireflow2.designer.eclipse.commands.AbstractCreateNodeCommand#
	 * createNodeWrapper()
	 */
	@Override
	protected NodeWrapper createNodeWrapper() {
		if (serviceCreationCommand!=null && serviceCreationCommand.isCanceled()){
			return null;
		}
		
		SubProcessWrapper subflowWrapper = null;
		if (this.parentWrapper instanceof SubProcessWrapper) {
			subflowWrapper = (SubProcessWrapper) this.parentWrapper;
		} else {
			subflowWrapper = ((NodeWrapper) this.parentWrapper)
					.getSubProcessWrapper();
		}
		NodeWrapper tmpNodeWrapper = null;
		SubProcess subflow = (SubProcess) subflowWrapper.getWorkflowModelElement();

		//1、构造Activity
		String name = "";
		if (this.serviceCreationCommand!=null){
			name = serviceCreationCommand.getServiceDefWrapper().getName();
		}else{
			name=findANewNodeName(subflow, "Activity");
		}
		String displayName = name;
		if (this.serviceCreationCommand!=null){
			displayName = "调用"+ serviceCreationCommand.getServiceDefWrapper().getDisplayName();
		}
		
		Activity activity = new ActivityImpl(
				(SubProcess) subflowWrapper.getWorkflowModelElement(), name);
		
		activity.setDisplayName(displayName);
		//1.1 如果创建了Service则，则构建ServiceBinding
		if (this.serviceCreationCommand!=null && this.serviceCreationCommand.getServiceDefWrapper()!=null
				&& this.serviceCreationCommand.getServiceBinding()!=null){
			activity.setServiceBinding(this.serviceCreationCommand.getServiceBinding());
		}
		
		
		//2、构造图形对象
		String shapeId = UUID.randomUUID().toString();
		ActivityShape activityShape = new ActivityShapeImpl(shapeId);
		activityShape.setWorkflowElementRef(activity.getId());

		RectangleImpl actRect = new RectangleImpl();

		BoundsStyleImpl boundsStyle = new BoundsStyleImpl();
		boundsStyle.setCornerType(BoundsStyle.LINETYPE_DASHED);
		boundsStyle.setRadius(11);
		boundsStyle.setColor("#4682B4");
		BoundsImpl bounds = new BoundsImpl();
		bounds.setBoundsStyle(boundsStyle);
		bounds.setUpperLeftCorner(new PointImpl(rect.x, rect.y));

		bounds.setWidth(rect.width > 108 ? rect.width : 108);
		bounds.setHeight(rect.height > 72 ? rect.height : 72);

		FulfilStyle fulfilStyle = new FulfilStyleImpl();
		fulfilStyle.setColor("#F0FFFF");
		fulfilStyle.setGradientStyle(FulfilStyle.GRADIENT_STYLE_LEFT2RIGHT);
		actRect.setFulfilStyle(fulfilStyle);

		Font font = new FontImpl();
		font.setColor("#191970");
		font.setSize(10);
		font.setWeight(Font.FONT_WEIGHT_BOLD);

		if (actRect.getContent() == null) {
			Label lb = new LabelImpl();
			lb.setFont(font);
			actRect.setContentLabel(lb);
		} else {
			actRect.getContentLabel().setFont(font);
		}

		actRect.setBounds(bounds);
		activityShape.setShape(actRect);

		//3、构造Wrapper
		tmpNodeWrapper = new ActivityWrapper(subflowWrapper, activity,
				activityShape);

		return tmpNodeWrapper;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.fireflow2.designer.eclipse.commands.AbstractCreateNodeCommand#
	 * findANewNodeName(org.fireflow.pdl.fpdl20.process.Subflow,
	 * java.lang.String)
	 */
	@Override
	protected String findANewNodeName(SubProcess subflow, String nodeType) {
		boolean exist = true;
		int n = 1;
		List nodes = null;
		if (nodeType.equals("StartNode")){
			nodes = subflow.getStartNodes();
		}
		else if (nodeType.equals("Activity")){
			nodes = subflow.getActivities();
		}else if (nodeType.equals("Router")){
			nodes = subflow.getRouters();
		}else if (nodeType.equals("EndNode")){
			nodes = subflow.getEndNodes();
		}
		
		String name = nodeType
			+ (nodes.size() + n);	
		if (nodes==null || nodes.size()==0){
			return name;
		}		
		while(exist){
			boolean found = false;
			for (int i=0;i<nodes.size();i++){
				ModelElement node = (ModelElement)nodes.get(i);
				if (name.equals(node.getName())){
					n++;
					name = nodeType
						+ (nodes.size() + n);
					found = true;
					break;
				}
			}
			if (!found){
				exist=false;
			}
		}
		return name;
	}

}
